Perplexity to Scrapbox Converter
まだCSSなど未調整でださいが使いやすくなったのでよしとする
コードもがちゃがちゃしているが使えればよい
HTMLはfigmaでざっくりUI作った奴をLLMに投げたら作ってくれた、便利cak.icon https://gyazo.com/acb996f69501ec7fdd922502baa2b707
万が一自分も使いたいという人がいたときと、うっかり消しちゃった時のバックアップとしてのエリア
GASを開いて以下のformat.gsとindex.htmlの2つのファイルを作り、デプロイすると使える 現在perplexity.iconのproアカウントがあるのでperplexity.iconに特化したやつを作っているが、基本markdownなのでちょっと調整すればClaudeやCPTにも使えるかも code:format.gs
function formatText(inputText) {
let text = inputText;
text = normalizeBoldText(text);
text = modifyMarkdownHeaders(text);
text = convertListItems(text);
text = formatSquareBrackets(text);
text = removeExtraSpaces(text);
text = formatTex(text);
text = convertEmphasizedText(text);
text = convertCodeBlock(text);
return text;
}
// バッククォートを削除
function removeBackticks(inputText) {
return inputText.replace(/`/g, '');
}
// テキスト内のヘッダーを修正
function modifyMarkdownHeaders(inputText) {
// 正規表現パターン
let headerPattern = /^(#+)\s+(.*)$/gm;
// ヘッダーを修正する関数
function replaceHeader(match, hashes, headerText) {
let level = hashes.length; // ヘッダーの#の数によってレベルを判定
// バッククォートを削除
headerText = removeBackticks(headerText);
// ヘッダーテキストを修正
let modifiedHeader;
if (level === 1 || level === 2) {
modifiedHeader = [** ${headerText}];
} else {
modifiedHeader = [* ${headerText}];
}
return modifiedHeader;
}
let modifiedText = inputText.replace(headerPattern, replaceHeader);
return modifiedText;
}
// テキスト内の太字を普通のテキストに変換
function normalizeBoldText(inputText) {
// **テキスト** を普通のテキストに変換する正規表現パターン
let boldPattern = /\*\*(.*?)\*\*/g;
// 太字を普通のテキストに変換する関数
function replaceBold(match, boldText) {
return boldText; // 太字部分のみを返す
}
let normalizedText = inputText.replace(boldPattern, replaceBold);
return normalizedText;
}
// リストアイテムを変換
function convertListItems(inputText) {
// リストアイテムを変換する正規表現パターン
let listItemPattern = /^(\s*)-\s+(.*)$/gm;
// リストアイテムを変換する関数
function replaceListItem(match, leadingSpaces, listItemText) {
return leadingSpaces + " " + listItemText; // 先頭のスペースにタブを追加
}
let convertedText = inputText.replace(listItemPattern, replaceListItem);
return convertedText;
}
// 正規表現で連続する半角スペースを一つに置換する
function removeExtraSpaces(inputText) {
return inputText.replace(/(?!\n)\s\s+/g, ' ');
}
function formatSquareBrackets(inputText) {
// 正規表現で "数字" に一致する部分を "*数字 " に変換する return inputText.replace(/\(\d+)\/g, (match, p1) => *${p1} ); }
//$$hoge$$を$ hogeにする
function formatTex(inputText) {
// 正規表現で "数字" に一致する部分を "*数字 " に変換する return inputText.replace(/\$\$(.*?)\$\$/g, '$ $1');
}
//コードブロックの整形
function convertCodeBlock(inputText) {
return inputText.replace(/(python|javascript|.*)\n([\s\S]*?)/g, function(match, lang, code) {
let extension = '';
if (lang === 'python') {
extension = '.py';
} else if (lang === 'javascript') {
extension = '.js';
}
let lines = code.split('\n');
let prevSpaces = ' ';
let newCode = lines.map(line => {
if (line.trim() === '') {
return prevSpaces + line;
}
let newLine = ' ' + line;
prevSpaces = newLine.match(/^\s*/)0; return newLine;
}).join('\n');
return code:${lang}${extension}\n${newCode};
});
}
//強調部分をリンクに
function convertEmphasizedText(inputText) {
inputText = inputText.replace(/\*(\S(?:.*?\S)?)\*/g, '$1'); return inputText;
}
code:index.html
<!DOCTYPE html>
<html>
<head>
<style>
width: 80%;
height: 150px;
margin-bottom: 10px;
padding: 10px;
}
width: 80%;
height: 150px;
margin-bottom: 10px;
padding: 10px;
font-family: monospace;
white-space: pre-wrap; /* テキストを改行に応じて折り返す */
overflow-x: auto; /* 横スクロール可能にする */
}
padding: 10px 20px;
margin-right: 10px;
cursor: pointer;
}
position: relative;
}
position: absolute;
top: 10px;
right: 10px;
color: white;
border: none;
border-radius: 3px;
}
.notification {
display: none;
position: fixed;
top: 10px;
right: 10px;
color: white;
padding: 10px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
z-index: 1000;
}
</style>
</head>
<body>
<h1>Perplexity to Scrapbox Converter</h1>
<p>Perplexityで出力したものを良い感じにScrapboxに貼れるように整形します</p>
<textarea id="inputArea" placeholder="input area"></textarea>
<br/>
<button id="convertButton">convert</button>
<br/>
<div id="outputContainer">
<div id="notification" class="notification">Copied to clipboard!</div>
<pre id="outputArea"></pre>
<button id="copyButton">Copy</button>
</div>
<script>
document.getElementById("convertButton").addEventListener("click", function() {
var inputText = document.getElementById("inputArea").value;
// サーバーサイドの関数を呼び出し、結果を取得
google.script.run.withSuccessHandler(function(output) {
document.getElementById("outputArea").textContent = output;
}).formatText(inputText);
});
document.getElementById("copyButton").addEventListener("click", function() {
var outputArea = document.getElementById("outputArea");
var range = document.createRange();
range.selectNodeContents(outputArea);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
try {
document.execCommand("copy");
showNotification();
} catch (err) {
alert("Failed to copy!");
}
selection.removeAllRanges();
});
function showNotification() {
const notification = document.getElementById('notification');
notification.style.display = 'block';
setTimeout(() => {
notification.style.display = 'none';
}, 1000); // 3秒後に消える
}
</script>
</body>
</html>